home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / (A)P / (A)P1.ADF / life / life.c < prev    next >
C/C++ Source or Header  |  1987-05-25  |  7KB  |  258 lines

  1. /*
  2.  *   Here is a simple LIFE program which tests the blitter operations.
  3.  *   It does not extensively test the shifts or anything, but it makes
  4.  *   sure that the basic interface is correct.
  5.  */
  6. #define HSIZE (320)
  7. #define MODULO ((HSIZE + 15)/16)*16
  8. #define VSIZE (190)
  9. #define RASTSIZE (MODULO / 16 * VSIZE)
  10. #include "structures.h"
  11. short *a, *b, *c, *d, *e, *t1=NULL, *t2=NULL, *t3=NULL, *t4=NULL, *t5=NULL ;
  12. short noplanes ;
  13. struct GfxBase *GfxBase = NULL ;     /* the GfxBase */
  14. struct IntuitionBase *IntuitionBase = NULL ; /* the IntuitionBase */
  15. struct Screen *myscreen = NULL ;
  16. struct NewScreen mynewscreen = {
  17.    0,                                         /* left edge */
  18.    0,                                         /* top edge */
  19.    320,                                       /* width */
  20.    200,                                       /* height */
  21.    2,                                         /* depth (change for color?)*/
  22.    1,                                         /* detail pen */
  23.    2,                                         /* block pen */
  24.    0,                                         /* screen mode */
  25.    CUSTOMSCREEN,                              /* type */
  26.    NULL,                                      /* use default font */
  27.    (UBYTE *)"LIFE by Tomas Rokicki",          /* title */
  28.    NULL,                                      /* initialize this gadget field */
  29.    NULL } ;                                   /* no bitmap supplied */
  30. /*
  31.  *   This routine gets a raster for temporary storage.
  32.  */
  33. short *myalloc() {
  34.    void *AllocMem() ;
  35.    void *p ;
  36.  
  37.    if ((p=AllocMem(2L*RASTSIZE, MEMF_CHIP | MEMF_CLEAR))==NULL) {
  38.       printf("Could not allocate raster data\n") ;
  39.       cleanup() ;
  40.    }
  41.    return(p) ;
  42. }
  43. /*
  44.  *   Here we set things up.
  45.  */
  46. initialize() {
  47.    initblitdata() ;
  48.    if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary(
  49.       "intuition.library",0L))==NULL ||
  50.        (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L))
  51.       ==NULL) {
  52.       printf("Couldn't open libraries.\n") ;
  53.       cleanup() ;
  54.    }
  55.    if ((myscreen = OpenScreen(&mynewscreen))==NULL) {
  56.       printf("Couldn't open screen.\n") ;
  57.       cleanup() ;
  58.    }
  59.    a = ((short *)(myscreen->BitMap.Planes[0])) + 200 ;
  60.    b = ((short *)(myscreen->BitMap.Planes[1])) + 200 ;
  61.    c = ((short *)(myscreen->BitMap.Planes[2])) + 200 ;
  62.    d = ((short *)(myscreen->BitMap.Planes[3])) + 200 ;
  63.    e = ((short *)(myscreen->BitMap.Planes[4])) + 200 ;
  64.    t1 = myalloc() ;
  65.    t2 = myalloc() ;
  66.    t3 = myalloc() ;
  67.    t4 = myalloc() ;
  68.    t5 = myalloc() ;
  69. }
  70. /*
  71.  *   Exit routine.
  72.  */
  73. cleanup() {
  74.    if (myscreen != NULL)
  75.       CloseScreen(myscreen) ;
  76.    myscreen = NULL ;
  77.    if (IntuitionBase)
  78.       CloseLibrary(IntuitionBase) ;
  79.    IntuitionBase = NULL ;
  80.    if (GfxBase)
  81.       CloseLibrary(GfxBase) ;
  82.    GfxBase = NULL ;
  83.    if (t1)
  84.       FreeMem(t1, 2L*RASTSIZE) ;
  85.    if (t2)
  86.       FreeMem(t2, 2L*RASTSIZE) ;
  87.    if (t3)
  88.       FreeMem(t3, 2L*RASTSIZE) ;
  89.    if (t4)
  90.       FreeMem(t4, 2L*RASTSIZE) ;
  91.    if (t5)
  92.       FreeMem(t5, 2L*RASTSIZE) ;
  93.    exit(0) ;
  94. }
  95. #define PARITY (0x96)
  96. #define CARRY (0xe8)
  97. #define PARITY2 (0x3c)
  98. #define CARRY2 (0xc0)
  99. #define SPECIAL1 (0x12)
  100. #define SPECIAL2 (0xe0)
  101. #define COPY (0xf0)
  102. /*
  103.  *   Does one LIFE generation.  Fancy algorithm uses only 10 blits.  If
  104.  *   anyone can improve this, please let me know.
  105.  */
  106. dogeneration() {
  107.    OwnBlitter() ;
  108. /*
  109.  *   Take horizontal sums.
  110.  */
  111.    blit(a, 0, 1,
  112.         a, 2, 1,
  113.         a, 1, 1,
  114.         t1, 1, 1,
  115.         MODULO, HSIZE-2, VSIZE-2, PARITY) ;
  116.    blit(a, 0, 1,
  117.         a, 2, 1,
  118.         a, 1, 1,
  119.         t2, 1, 1,
  120.         MODULO, HSIZE-2, VSIZE-2, CARRY) ;
  121. /*
  122.  *   Take sums for middle row.
  123.  */
  124.    blit(a, 0, 1,
  125.         a, 2, 1,
  126.         a, 1, 1,
  127.         t3, 1, 1,
  128.         MODULO, HSIZE-2, VSIZE-2, PARITY2) ;
  129.    blit(a, 0, 1,
  130.         a, 2, 1,
  131.         a, 1, 1,
  132.         t4, 1, 1,
  133.         MODULO, HSIZE-2, VSIZE-2, CARRY2) ;
  134. /*
  135.  *   Now, sum each of the three columns.
  136.  */
  137.    blit(t1, 1, 0,
  138.         t1, 1, 2,
  139.         t3, 1, 1,
  140.         t5, 1, 1,
  141.         MODULO, HSIZE-2, VSIZE-2, PARITY) ;
  142.    blit(t1, 1, 0,
  143.         t1, 1, 2,
  144.         t3, 1, 1,
  145.         t3, 1, 1,
  146.         MODULO, HSIZE-2, VSIZE-2, CARRY) ;
  147.    blit(t2, 1, 0,
  148.         t2, 1, 2,
  149.         t4, 1, 1,
  150.         t1, 1, 1,
  151.         MODULO, HSIZE-2, VSIZE-2, PARITY) ;
  152.    blit(t2, 1, 0,
  153.         t2, 1, 2,
  154.         t4, 1, 1,
  155.         t4, 1, 1,
  156.         MODULO, HSIZE-2, VSIZE-2, CARRY) ;
  157. /*
  158.  *   Now, check high two order bits, then combine with original and
  159.  *   low order bit.
  160.  */
  161.    blit(t1, 1, 1,
  162.         t4, 1, 1,
  163.         t3, 1, 1,
  164.         t2, 1, 1,
  165.         MODULO, HSIZE-2, VSIZE-2, SPECIAL1) ;
  166. /*
  167.  *   Before we do the final write, we copy bits down one generation.
  168.  */
  169.    switch (noplanes) {
  170. case 5:
  171.    blit(d, 1, 1,
  172.         d, 1, 1,
  173.         d, 1, 1,
  174.         e, 1, 1,
  175.         MODULO, HSIZE-2, VSIZE-2, COPY) ;
  176. case 4:
  177.    blit(c, 1, 1,
  178.         c, 1, 1,
  179.         c, 1, 1,
  180.         d, 1, 1,
  181.         MODULO, HSIZE-2, VSIZE-2, COPY) ;
  182. case 3:
  183.    blit(b, 1, 1,
  184.         b, 1, 1,
  185.         b, 1, 1,
  186.         c, 1, 1,
  187.         MODULO, HSIZE-2, VSIZE-2, COPY) ;
  188. case 2:
  189.    blit(a, 1, 1,
  190.         a, 1, 1,
  191.         a, 1, 1,
  192.         b, 1, 1,
  193.         MODULO, HSIZE-2, VSIZE-2, COPY) ;
  194. default: ;
  195. }
  196.    blit(t2, 1, 1,
  197.         t5, 1, 1,
  198.         a, 1, 1,
  199.         a, 1, 1,
  200.         MODULO, HSIZE-2, VSIZE-2, SPECIAL2) ;
  201.    DisownBlitter() ;
  202. }
  203. /*
  204.  *   Random number generator; probably not a very good one.
  205.  */
  206. int rnd(i)
  207. int i ;
  208. {
  209.    static long seed = 323214521 ;
  210.    long rval ;
  211.  
  212.    seed = seed * 123213 + 121 ;
  213.    rval = (seed >> 5) & 65535 ;
  214.    return ((i * rval) >> 16) ;
  215. }
  216. /*
  217.  *   Main routine.  If called with no arguments, makes 1 bit plane screen.
  218.  *   Otherwise, first argument is used as the number of bit planes.
  219.  */
  220. main (argc, argv)
  221. int argc ;
  222. char *argv[] ;
  223. {
  224.    register int i ;
  225.    register int x, y ;
  226.    long t1[3], t2[3] ;
  227.  
  228.    if (argc < 2 || sscanf(argv[1], "%d", &noplanes) < 1 || noplanes < 1
  229.                 || noplanes > 5)
  230.       noplanes = 1 ;
  231.    mynewscreen.Depth = noplanes ;
  232.    initialize() ;
  233.    for (i=0; i<RASTSIZE; i++)
  234.       a[i] = 0 ;
  235.    a[2010] = 0x0060 ;
  236.    a[2030] = 0x00c0 ;
  237.    a[2050] = 0x0040 ;
  238.    i = 0 ;
  239.    DateStamp(t1) ;
  240.    x = 12 ;
  241.    while (x != 0 || y != 100) {
  242.       x = rnd(HSIZE-2) + 1 ;
  243.       y = rnd(VSIZE-2) + 1 ;
  244.       a[y*20+(x>>4)] |= 1 << (15 - (x & 15)) ;
  245.       dogeneration() ;
  246.       i++ ;
  247.       x = myscreen->MouseX ;
  248.       y = myscreen->MouseY ;
  249.    }
  250.    DateStamp(t2) ;
  251.    printf("%ld ticks %d generations\n",
  252.       t2[2]-t1[2] +
  253.       (t2[1]-t1[1]) * 3000L +
  254.       (t2[0]-t1[0]) * 4320000L, i) ;
  255.    printf("Done.\n") ;
  256.    cleanup() ;
  257. }
  258.